<template>
    <div>
        <el-form label-width="6rem">
            <el-form-item label="SPU名称">
                <el-input placeholder="请输入SPU名称" v-model="spuParams.spuName"></el-input>
            </el-form-item>
            <el-form-item label="SPU品牌">
                <el-select v-model="spuParams.tmId">
                    <el-option v-for="(item, index) in AllTrademark" :key="item.id" :label="item.tmName"
                    :value="item.id"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="SPU描述">
                <el-input type="textarea" placeholder="请输入SPU描述" v-model="spuParams.description"></el-input>
            </el-form-item>
            <el-form-item label="SPU图片">
                <!--
                v-model:file-list: 展示默认图片
                action: 上传图片的接口地址
                on-preview: 照片墙点击预览按钮时触发的钩子
                on-remove: 照片墙点击删除时触发的钩子
            -->
                <el-upload v-model:file-list="imgList" action="/api/admin/product/fileUpload" list-type="picture-card"
                :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="limitUpload">
                    <el-icon>
                        <Plus />
                    </el-icon>
                </el-upload>
                <el-dialog v-model="dialogVisible">
                    <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 80%; height: 80%" />
                </el-dialog>
            </el-form-item>
            <el-form-item label="SPU销售属性">
                <el-select style="width: 12rem; margin-right: 0.625rem;" v-model="saleAttrIdAndValueName"
                :placeholder="unSelectSaleAttr.length ? `还未选择${unSelectSaleAttr.length}个` : '无'">
                    <el-option :value="`${item.id}:${item.name}`" v-for="(item, index) in unSelectSaleAttr"
                    :key="item.id" :label="item.name"></el-option>
                </el-select>
                <el-button type="primary" size="default" icon="Plus" @click="addSaleAttr"
                :disabled="saleAttrIdAndValueName ? false : true">添加属性值</el-button>
                <el-table border style="margin-top: 0.625rem;" :data="saleAttr">
                    <el-table-column label="序号" type="index" align="center" width="80px"></el-table-column>
                    <el-table-column label="销售属性名称" width="120px" prop="saleAttrName"></el-table-column>
                    <el-table-column label="销售属性值">
                        <template #="{ row, $index }">
                            <el-tag style="margin: 0 .625rem;" v-for="(item, index) in row.spuSaleAttrValueList"
                            @close="row.spuSaleAttrValueList.splice(index, 1)" :key="row.id" class="mx-1" closable>
                                {{ item.saleAttrValueName }}
                            </el-tag>
                            <el-input placeholder="请输入属性值" size="small" style="width: 6.25rem"
                            v-if="row.flag == true" v-model="row.saleAttrValue" @blur="toLook(row)"></el-input>
                            <el-button type="primary" size="small" icon="Plus" v-else @click="toEdit(row)"></el-button>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="120px">
                        <template #="{ row, $index }">
                            <el-button type="primary" size="small" icon="Delete"
                                @click="saleAttr.splice($index, 1)"></el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" size="default" @click="save"
                :disabled="saleAttr.length > 0 ? false : true">保存</el-button>
                <el-button type="primary" size="default" @click="cancle">取消</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<script setup lang="ts">
import type { SpuData, Trademark, AllTrademark, SpuImg, SpuHasImg, SaleAttr, SaleAttrValue,
SaleAttrResponseData, HasSaleAttr, HasSaleAttrResponseData } from '@/api/product/spu/type'
import { reqAllTrademark, reqSpuImageList, reqSpuHasSaleAttr, reqAllSaleAttr, reqAddOrUpdateSpu} from '@/api/product/spu'
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'

let $emit = defineEmits(['changeScene'])
//存储已有的spu对象
let spuParams = ref<SpuData>({
    category3Id: '',
    spuName: '',
    tmId: '',
    description: '',
    spuImageList: [],
    spuSaleAttrList: []
})
//存储已有的spu数据
let AllTrademark = ref<Trademark[]>([])
let imgList = ref<SpuImg[]>([])
let saleAttr = ref<SaleAttr[]>([])
let hasSaleAttr = ref<HasSaleAttr[]>([])  //全部
//控制对话框的显示与隐藏
let dialogVisible = ref<boolean>(false)
//存储预览图片的地址
let dialogImageUrl = ref<string>('')
//将来收集还未选择的销售属性的id和name
let saleAttrIdAndValueName = ref<string>('')

//点击取消按钮，通知父组件切换场景为1，展示已有的SPU数据
const cancle = () => {
    $emit('changeScene', { flag: 0, params: 'update' })
}
//保存按钮的回调
const save = async () => {
    //整理参数
    spuParams.value.spuImageList = imgList.value.map((item: any) => {
        return {
            imgName: item.name,
            imgUrl: (item.response && item.response.data) || item.url
        }
    })
    spuParams.value.spuSaleAttrList = saleAttr.value
    //发请求添加SPU或更新已有的SPU
    let result = await reqAddOrUpdateSpu(spuParams.value)
    if (result.code == 200) {
        ElMessage({
            type: 'success',
            message: spuParams.value.id ? '更新成功' : '添加成功'
        })
        $emit('changeScene', { flag: 0, params: spuParams.value.id ? 'update' : 'add' })
    } else {
        ElMessage({
            type: 'error',
            message: spuParams.value.id ? '更新失败' : '添加失败'
        })
    }
}
//添加一个新的SPU初始化请求方法
const initSpu = async (c3Id: number | string) => {
    //清空数据
    //清空照片墙
    imgList.value = []
    //清空销售属性
    saleAttr.value = []
    saleAttrIdAndValueName.value = ''
    Object.assign(spuParams.value, {
        category3Id: '',
        spuName: '',
        tmId: '',
        description: '',
        spuImageList: [],
        spuSaleAttrList: []
    })

    //存储三级分类的id
    spuParams.value.category3Id = c3Id
    //获取全部品牌的数据
    let result1: AllTrademark = await reqAllTrademark()
    //获取整个项目的全部spu的销售属性
    let result2: HasSaleAttrResponseData = await reqAllSaleAttr()

    //存储已有的spu数据
    AllTrademark.value = result1.data
    hasSaleAttr.value = result2.data
}

const initHasSpuData = async (spu: SpuData) => {
    //spu：即为父组件传递过来的不完整的spu数据
    //存储已有的spu对象，将来在模板中展示
    spuParams.value = spu
    //获取全部品牌的数据
    let result1: AllTrademark = await reqAllTrademark()
    //获取某品牌下售卖商品的图片
    let result2: SpuHasImg = await reqSpuImageList((spu.id as number))
    //获取已有的spu的销售属性的数据
    let result3: SaleAttrResponseData = await reqSpuHasSaleAttr((spu.id as number))
    //获取整个项目的全部spu的销售属性
    let result4: HasSaleAttrResponseData = await reqAllSaleAttr()

    //存储已有的spu数据
    AllTrademark.value = result1.data
    imgList.value = result2.data.map(item => {
        return {
            name: item.imgName,
            url: item.imgUrl
        }
    })
    saleAttr.value = result3.data
    hasSaleAttr.value = result4.data
}
//照片墙点击预览按钮时触发的钩子
const handlePictureCardPreview = (file: any) => {
    dialogImageUrl.value = file.url
    //对话框弹出
    dialogVisible.value = true
}
//照片墙点击删除时触发的钩子
const handleRemove = () => {
}
//照片上传限制
const limitUpload = (rawFile: any) => {
    //上传文件前约束文件的类型和大小
    if (rawFile.type == 'image/jpeg' || rawFile.type == 'image/png' || rawFile.type == 'image/gif') {
        if (rawFile.size < 4194304) {
            return true
        } else {
            ElMessage({
                type: 'error',
                message: '上传的文件必须小于4M'
            })
        }
    } else {
        ElMessage({
            type: 'error',
            message: '上传的文件必须为.jpeg或.png或.gif类型的图片'
        })
        return false
    }
}
//添加销售属性的方法
const addSaleAttr = () => {
    const [baseSaleAttrId, saleAttrName] = saleAttrIdAndValueName.value.split(':')
    //准备一个新的销售属性对象将来带给服务器
    let newSaleAttr: SaleAttr = {
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: []
    }
    saleAttr.value.push(newSaleAttr)
    //清空收集的数据
    saleAttrIdAndValueName.value = ''
}
//属性值按钮的点击事件
const toEdit = (row: SaleAttr) => {
    row.flag = true
    row.saleAttrValue = ''
}
//表单元素失去焦点的事件回调
const toLook = (row: SaleAttr) => {
    //收集属性id与属性名字
    const { baseSaleAttrId, saleAttrValue } = row
    //整理成服务器需要的属性值名字
    let newSaleAttrValue: SaleAttrValue = {
        baseSaleAttrId,
        saleAttrValueName: (saleAttrValue as string)
    }
    //非法情况判定
    if ((saleAttrValue as string).trim() == '') {
        ElMessage({
            type: 'error',
            message: '属性值不能为空'
        })
        return
    }
    //判定属性值在方法中是否存在
    let repeat = row.spuSaleAttrValueList.find(item => {
        return item.saleAttrValueName == saleAttrValue
    })
    if (repeat) {
        ElMessage({
            type: 'error',
            message: '属性值重复'
        })
        return
    }
    //追加新的属性值对象
    row.spuSaleAttrValueList.push(newSaleAttrValue)
    //切换为查看模式
    row.flag = false
}

//计算当前SPU还未选择的销售属性
let unSelectSaleAttr = computed(() => {
    let unSelectArr = hasSaleAttr.value.filter(item => {
        return saleAttr.value.every(item1 => {
            return item.name != item1.saleAttrName
        })
    })
    return unSelectArr
})

//对外暴露
defineExpose({ initHasSpuData, initSpu })
</script>

<style scoped lang="scss"></style>